package com.zzq.config;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class OssClientFactory {
    @Value("${aliyun.oss.stsendpoint}")
    private String stsendpoint;
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.oss.bucketName}")
    private String bucketname;
    @Value("${aliyun.oss.roleArn}")
    private String roleArn;
    @Value("${aliyun.oss.roleSessionName}")
    private String roleSessionName;
    @Value("${aliyun.oss.durationSeconds}")
    private Long durationSeconds;

    @Autowired
    private ApplicationContext  applicationContext;
    String policy = "{\n" +
            "  \"Statement\": [\n" +
            "    {\n" +
            "      \"Action\": [\n" +
            "        \"oss:PutObject\",\n" +
            "        \"oss:GetObject\"\n" +
            "\n" +
            "      ],\n" +
            "      \"Effect\": \"Allow\",\n" +
            "      \"Resource\": [\n" +
            "        \"acs:oss:*:*:zzqkj/*\",\n" +
            "        \"acs:oss:*:*:zzqjt/*\",\n" +
            "        \"acs:oss:*:*:zzqjt-test/*\",\n" +
            "        \"acs:oss:*:*:zzqkj-test/*\"\n" +
            "      ]\n" +
            "    }\n" +
            "  ],\n" +
            "  \"Version\": \"1\"\n" +
            "}";



    private OSS ossClient; // 用于存储实例化的 OSS 客户端

    public OssClientFactory() {
        log.info("OssClientRefresh Bean initialized.");
    }

    public OSS ossClient() {
        // 初始化 OSS 客户端的逻辑
        return createNewOss(); // 创建初始 OSS 客户端
    }

//    @Primary
//    @Bean
//    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 设置为原型作用域
//    public OSS ossClientBean() {
//        // 初始化 OSS 客户端的逻辑
//        return createNewOss(); // 创建初始 OSS 客户端
//    }

    // 定时刷新 OSS 客户端实例
//    @Scheduled(fixedRate = 1800000) // 例如，每隔 1 小时执行一次
//    public void refreshOssClient() {
//        // 获取 AutowireCapableBeanFactory
//        AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
//
//
//        // 重新创建和初始化 ossClientBean 实例
//        OSS newOssClientBean = createNewOss();
//        beanFactory.initializeBean(newOssClientBean, "ossClient");
//
//    }
    private  OSS createNewOss(){
        String temporary_accessKeyId = null;
        String temporary_accessKeySecret = null;
        String securityToken = null;
        try {

            // regionId表示RAM的地域ID。以华东1（杭州）地域为例，regionID填写为cn-hangzhou。也可以保留默认值，默认值为空字符串（""）。
            String regionId = "";
            // 添加endpoint。适用于Java SDK 3.12.0及以上版本。
            DefaultProfile.addEndpoint(regionId, "Sts", stsendpoint);
            // 添加endpoint。适用于Java SDK 3.12.0以下版本。
            // DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
            // 构造default profile。
            IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            // 构造client。
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            // 适用于Java SDK 3.12.0及以上版本。
            request.setSysMethod(MethodType.POST);
            // 适用于Java SDK 3.12.0以下版本。
            //request.setMethod(MethodType.POST);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            request.setDurationSeconds(durationSeconds);
            final AssumeRoleResponse response = client.getAcsResponse(request);
            log.info("Expiration: {}",response.getCredentials().getExpiration());
            log.info("Access Key Id: {}", response.getCredentials().getAccessKeyId());
            log.info("Access Key Secret: {}",response.getCredentials().getAccessKeySecret());
            log.info("Security Token: {}",response.getCredentials().getSecurityToken());
            log.info("RequestId: {}",response.getRequestId());

            temporary_accessKeyId=response.getCredentials().getAccessKeyId();
            temporary_accessKeySecret=response.getCredentials().getAccessKeySecret();
            securityToken=response.getCredentials().getSecurityToken();
            OSS ossClient = new OSSClientBuilder().build(
                    endpoint,
                    temporary_accessKeyId,
                    temporary_accessKeySecret,
                    securityToken);
            return ossClient;
        } catch (ClientException e) {
            log.error("oss报错");
            log.error("Failed：");
            log.error("Error code: {}" , e.getErrCode());
            log.error("Error message: {}" , e.getErrMsg());
            log.error("RequestId: {}" , e.getRequestId());
        }
        return null;
    }
}
